/**
 * FileContentManager is a Java based file manager desktop application, it can
 * show, edit and manipulate the content of the files archived inside a zip.
 * 
 * Copyright (C) 2007
 * 
 * Created by Camila Sanchez [http://mimix.wordpress.com/], Rafael Naufal
 * [http://rnaufal.livejournal.com] and Rodrigo [rdomartins@gmail.com]
 * 
 * FileContentManager is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with FileContentManager; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package br.com.jteam.jfcm.gui;

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;

import br.com.jteam.jfcm.controller.EventDispatchService;
import br.com.jteam.jfcm.controller.Subscriber;
import br.com.jteam.jfcm.controller.event.Event;
import br.com.jteam.jfcm.controller.event.OpenFileEvent;
import br.com.jteam.jfcm.controller.event.OpenHistoryFileEvent;
import br.com.jteam.jfcm.controller.event.ShowImageEvent;
import br.com.jteam.jfcm.controller.event.ShowTextEvent;
import br.com.jteam.jfcm.controller.event.UpdateFileHistoryEvent;
import br.com.jteam.jfcm.controller.listener.ExitApplicationListener;
import br.com.jteam.jfcm.controller.listener.OpenAboutDialogListener;
import br.com.jteam.jfcm.controller.listener.OpenFileListener;
import br.com.jteam.jfcm.controller.listener.ShowHistoryFileContentListener;
import br.com.jteam.jfcm.gui.adapter.FileListContentAdapterException;
import br.com.jteam.jfcm.gui.adapter.FileListPresentationContentAdapter;
import br.com.jteam.jfcm.gui.bundle.BaseBundle;
import br.com.jteam.jfcm.gui.menu.AbstractMenuItemFactory;
import br.com.jteam.jfcm.gui.menu.MenuType;
import br.com.jteam.jfcm.gui.panel.ContentPanel;
import br.com.jteam.jfcm.gui.panel.TreePanel;

/**
 * Constr&oacute;i os componentes de apresenta&ccedil;&atilde;o do
 * FileContentViewer e &eacute; notificado da ocorr&ecirc;ncia de
 * {@link UpdateFileHistoryEvent}.
 * 
 * @see br.com.jteam.jfcm.controller.event.UpdateFileHistoryEvent
 */
public class FCVGUIBuilder implements GUIBuilder, Subscriber
{
	/**
	 * Item de menu "Sobre".
	 */
	private JMenuItem aboutMenuItem;

	/**
	 * Adaptador para a manipula&ccedil;&atilde;o de arquivos abertos.
	 */
	private FileListPresentationContentAdapter adapter;

	private JSplitPane splitPane;

	/**
	 * Item de menu "Sair".
	 */
	private JMenuItem exitMenuItem;

	/**
	 * Menu "Arquivo".
	 */
	private JMenu fileMenu;

	/**
	 * Menu "Ajuda".
	 */
	private JMenu helpMenu;

	/**
	 * Lista e itens de menu que representam o hist&oacute;rico de arquivos
	 * abertos.
	 */
	private List<JMenuItem> historyFileMenuItens = new ArrayList<JMenuItem>();

	/**
	 * Frame principal.
	 */
	private MainFrame mainFrame;

	/**
	 * Barra de menus.
	 */
	private JMenuBar menuBar;

	/**
	 * Item de menu "Abrir".
	 */
	private JMenuItem openMenuItem;

	/**
	 * 
	 * @param adapter
	 *            Adaptador para a manipula&ccedil;&atilde;o de arquivos
	 *            abertos. N&atilde;o pode ser nulo.
	 * @throws IllegalArgumentException
	 *             Caso adapter seja nulo.
	 * 
	 */
	public FCVGUIBuilder(FileListPresentationContentAdapter adapter)
	{
		if (adapter == null)
		{
			throw new IllegalArgumentException("Null adapter.");
		}
		this.adapter = adapter;
	}

	public void createContentContainer()
	{
		TreePanel treePanel = new TreePanel();
		ContentPanel contentPanel = new ContentPanel();
		EventDispatchService service = EventDispatchService.getInstance();
		service.subscribe(OpenFileEvent.class, treePanel);
		service.subscribe(OpenHistoryFileEvent.class, treePanel);
		service.subscribe(OpenHistoryFileEvent.class, contentPanel);
		service.subscribe(OpenFileEvent.class, contentPanel);
		service.subscribe(ShowImageEvent.class, contentPanel);
		service.subscribe(ShowTextEvent.class, contentPanel);
		JScrollPane treeScrollPane = new JScrollPane(treePanel);
		JScrollPane contentScrollPane = new JScrollPane(contentPanel);
		Dimension minimumSize = new Dimension(0, 0);
		treeScrollPane.setMinimumSize(minimumSize);
		contentScrollPane.setMinimumSize(minimumSize);
		splitPane =
						new JSplitPane(	JSplitPane.HORIZONTAL_SPLIT,
										treePanel,
										contentPanel);
		splitPane.setOneTouchExpandable(true);
		splitPane.setResizeWeight(0.25);
	}

	public void createHistoryFiles()
	{
		AbstractMenuItemFactory itemFactory =
						AbstractMenuItemFactory.getFactory(MenuType.MENU_ITEM);
		PresentationFileHistory fileHistory = adapter.getHistory();
		Iterator<PresentationFile<?>> fileIterator = fileHistory.iterator();
		int i = -1;
		try
		{
			while (fileIterator.hasNext())
			{
				PresentationFile<?> file = fileIterator.next();
				String text = ++i + " - " + file.getPath();
				JMenuItem historyItem;
				ShowHistoryFileContentListener listener =
								new ShowHistoryFileContentListener(adapter.openZipContent(file.getPath()));
				historyItem =
								itemFactory.create(	text,
													String.valueOf(i).charAt(0),
													listener);
				historyFileMenuItens.add(historyItem);
			}
		} catch (FileListContentAdapterException e)
		{
			JOptionPane.showMessageDialog(	null,
											BaseBundle.getValue("error.openning.file"));
		}
	}

	public void createMainFrame()
	{
		mainFrame = new MainFrame(BaseBundle.getValue("app.name"));
		EventDispatchService.getInstance().subscribe(	OpenFileEvent.class,
														mainFrame);
		EventDispatchService.getInstance()
							.subscribe(OpenHistoryFileEvent.class, mainFrame);
		mainFrame.setJMenuBar(menuBar);
		mainFrame.setContent(splitPane);
	}

	public void createMenuBar()
	{
		menuBar = new JMenuBar();
		menuBar.add(fileMenu);
		menuBar.add(helpMenu);
	}

	public void createMenuItens()
	{
		AbstractMenuItemFactory itemFactory =
						AbstractMenuItemFactory.getFactory(MenuType.MENU_ITEM);
		openMenuItem =
						itemFactory.create(	BaseBundle.getValue("menu.file.item.open"),
											BaseBundle	.getValue("menu.file.item.open.mnemonic")
														.charAt(0),
											new OpenFileListener(adapter));
		exitMenuItem =
						itemFactory.create(	BaseBundle.getValue("menu.file.item.exit"),
											BaseBundle	.getValue("menu.file.item.exit.mnemonic")
														.charAt(0),
											new ExitApplicationListener());
		aboutMenuItem =
						itemFactory.create(	BaseBundle.getValue("menu.help.item.about"),
											BaseBundle	.getValue("menu.help.item.about.mnemonic")
														.charAt(0),
											new OpenAboutDialogListener());
	}

	public void createMenus()
	{
		AbstractMenuItemFactory menuFactory =
						AbstractMenuItemFactory.getFactory(MenuType.MENU);
		fileMenu =
						(JMenu) menuFactory.create(	BaseBundle.getValue("menu.file"),
													BaseBundle	.getValue("menu.file.mnemonic")
																.charAt(0),
													null);
		helpMenu =
						(JMenu) menuFactory.create(	BaseBundle.getValue("menu.help"),
													BaseBundle	.getValue("menu.help.mnemonic")
																.charAt(0),
													null);
		fileMenu.add(openMenuItem);
		fileMenu.add(exitMenuItem);
		helpMenu.add(aboutMenuItem);
		if (!historyFileMenuItens.isEmpty())
		{
			fileMenu.addSeparator();
			for (JMenuItem item : historyFileMenuItens)
			{
				fileMenu.add(item);
			}
		}
	}

	public JFrame getMainFrame()
	{
		return mainFrame;
	}

	public void notify(Event event)
	{
		if (event.getClass().equals(UpdateFileHistoryEvent.class))
		{
			historyFileMenuItens.clear();
			createMenuItens();
			createHistoryFiles();
			createMenus();
			createMenuBar();
			mainFrame.setJMenuBar(menuBar);
			mainFrame.validate();
		}
	}
}